package com.kpx.app.utils;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.TextUtils;

import com.alibaba.sdk.android.oss.ServiceException;
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask;
import com.kpx.app.bean.UploadBean;
import com.kpx.app.listener.AliyunUploadListener;
import com.kpx.app.service.UploadService;
import com.kpx.app.utils.datautils.FileUtils;
import com.kpx.app.utils.datautils.LogUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 作者： Ryan
 * 描述：图片批量上传
 * 创建时间：2015/4/26 11:35.
 */
public class ImagesBulkUpload {
    private static final String TAG = ImagesBulkUpload.class.getSimpleName();
    /**
     * 正在上传的文件
     */
    private List<UploadBean> imagesUploading;
    /**
     * 上传失败的文件
     */
    private List<UploadBean> imagesUploadFailed = new ArrayList<UploadBean>();
    /**
     * 上传监听
     */
    private OnBulkImagesUploadListener onBulkImagesUploadListener;
    /**
     * 是否取消上传
     */
    private boolean cancelUploading;
    /**
     * 是否断点续传
     */
    boolean isResume;
    /**
     * 同时最大上传数量
     */
    private int maxUploadCount = 2;
    /***/
    private Context context;
    private HashMap<String, OSSAsyncTask> tasks = new HashMap<>();

    public ImagesBulkUpload(Context context, List<UploadBean> imagesUploading, boolean isResume) {
        this.imagesUploading = imagesUploading;
        this.context = context;
        this.isResume = isResume;
    }

    public ImagesBulkUpload(Context context, List<UploadBean> imagesUploading, boolean isResume, OnBulkImagesUploadListener onBulkImagesUploadListener) {
        this.imagesUploading = imagesUploading;
        this.context = context;
        this.isResume = isResume;
        setOnBulkImagesUploadListener(onBulkImagesUploadListener);
    }

    public void addUploadFiles(ArrayList<UploadBean> uploads) {
        if (imagesUploading != null) {
            if (imagesUploading.size() == 0) {
                for (int i = 0; i < uploads.size(); i++) {
                    imagesUploading.add(0, uploads.get(i).copy());
                }
                startUpload();
            } else {
                for (int i = 0; i < uploads.size(); i++) {
                    imagesUploading.add(0, uploads.get(i).copy());
                }
            }
        }
    }

    /**
     * 取消某个上传线程
     *
     * @param bean
     */
    public void cancelTask(UploadBean bean) {
        if (tasks.get(bean.getCloudKey()) != null) {
            tasks.get(bean.getCloudKey()).cancel();
            tasks.remove(bean.getCloudKey());
        }
    }

    public void beginUpload(UploadBean b) {
        if (tasks.size() >= 2) {
            if (tasks.get(0) != null) {
                tasks.get(0).cancel();
            }
            tasks.remove(0);
        }
        boolean isInList = false;
        for (int i = 0; i < imagesUploading.size(); i++) {
            if (imagesUploading.get(i).getCloudKey().equals(b.getCloudKey())) {
                isInList = true;
                imagesUploading.get(i).setStatus(UploadBean.UPLOAD_TYPE_UPLOADING);
                uploadFileBean(imagesUploading.get(i));
                break;
            }
        }
        if (!isInList) {
            b.setStatus(UploadBean.UPLOAD_TYPE_UPLOADING);
            imagesUploading.add(b);
            uploadFileBean(b);
        }
    }

    public void setOnBulkImagesUploadListener(OnBulkImagesUploadListener onBulkImagesUploadListener) {
        this.onBulkImagesUploadListener = onBulkImagesUploadListener;
    }

    public void cancelUploading() {
        setOnBulkImagesUploadListener(null);
        cancelUploading = true;
    }

    public void startUpload() {
//        for (int i = 0; i < ((imagesUploading.size() < maxUploadCount) ? imagesUploading.size() : maxUploadCount); i++) {
        upload(900,900);
//        }
    }

    /**
     * 进行上传
     */
    public void upload() {
        if (cancelUploading || imagesUploading == null || (imagesUploading != null && imagesUploading.size() == 0)) {
            return;
        }
        final UploadBean image = getUploadBean();
        if (image == null) {
            return;
        }
        if (TextUtils.isEmpty(image.getLocalPath()) || image.getLocalPath() == null || !new File(image.getLocalPath()).exists()) {
            image.setStatus(UploadBean.UPLOAD_TYPE_FAIL);
            imagesUploading.remove(image);
            image.setFailMsg("待上传文件不存在");
            if (onBulkImagesUploadListener != null) {
                onBulkImagesUploadListener.onImageUploadFailed(image);
                if (imagesUploading.size() == 0) {
                    onBulkImagesUploadListener.onFinished(imagesUploadFailed);
                    return;
                }
            }
            return;
        }
        uploadFileBean(image);
    }

    /**
     * 指定开始上传某个文件
     *
     * @param image
     */
    private void uploadFileBean(final UploadBean image) {
        try {
            AliyunFileUploader aliyunFileUploader = new AliyunFileUploader(image.localPath, image.cloudKey, image.bucketName, context, new AliyunUploadListener() {
                @Override
                public void onSuccess(String cloudKey, String sourceFilePath) {
                    for (int i = 0; i < imagesUploading.size(); i++) {
                        if (imagesUploading.get(i).getCloudKey().equals(cloudKey)) {
                            imagesUploading.remove(i);
                        }
                    }
                    if (onBulkImagesUploadListener != null) {
                        onBulkImagesUploadListener.onImageUploadSucceed(image);
                        if (imagesUploading.size() == 0) {
                            onBulkImagesUploadListener.onFinished(imagesUploadFailed);
                            return;
                        }
                    }

                    tasks.remove(cloudKey);
                    if (!cancelUploading) {
                        upload(900,900);
                    }
                }

                @Override
                public void onProgress(String cloudKey, long progress, long total) {
                    if (onBulkImagesUploadListener != null) {
                        onBulkImagesUploadListener.onImageUploadProgress(image, progress, total);
                    }
                }

                @Override
                public void onFailure(String cloudKey, ServiceException e) {
                    imagesUploadFailed.add(image);
                    tasks.remove(cloudKey);
                    for (int i = 0; i < imagesUploading.size(); i++) {
                        if (imagesUploading.get(i).getCloudKey().equals(cloudKey)) {
                            imagesUploading.remove(i);
                        }
                    }
                    if (!cancelUploading) {
                        upload(600,600);
                    }
                    if (onBulkImagesUploadListener != null) {
                        onBulkImagesUploadListener.onImageUploadFailed(image);
                        if (imagesUploading.size() == 0) {
                            onBulkImagesUploadListener.onFinished(imagesUploadFailed);
                            return;
                        }
                    }
                }
            });
            if (cancelUploading) {
                return;
            }
            OSSAsyncTask task;
            if (isResume) {
                task = aliyunFileUploader.uploadResume();
            } else {
                task = aliyunFileUploader.upload();
            }
            if (checkTask(image, task)) return;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    private boolean checkTask(UploadBean image, OSSAsyncTask task) {
        if (task != null) {
            tasks.put(image.getCloudKey(), task);
        } else {
            image.setStatus(UploadBean.UPLOAD_TYPE_FAIL);
            imagesUploading.remove(image);
            image.setFailMsg("上传框架初始化错误");
            if (onBulkImagesUploadListener != null) {
                onBulkImagesUploadListener.onImageUploadFailed(image);
                if (imagesUploading.size() == 0) {
                    onBulkImagesUploadListener.onFinished(imagesUploadFailed);
                    return true;
                }
            }
            if (!cancelUploading) {
                upload(600,600);
            }
            return true;
        }
        return false;
    }

    private UploadBean getUploadBean() {
        if (imagesUploading.size() > 0) {
            for (int i = 0; i < imagesUploading.size(); i++) {
                if (imagesUploading.get(i).getStatus() == UploadBean.UPLOAD_TYPE_WAITTING) {
                    return imagesUploading.get(i);
                }
            }
        } else if (imagesUploading.size() == 0 && UploadService.uploadBeens.size() > 0) {
            for (int i = 0; i < UploadService.uploadBeens.size(); i++) {
                if (UploadService.uploadBeens.get(i).getStatus() == UploadBean.UPLOAD_TYPE_WAITTING || !TextUtils.isEmpty(UploadService.uploadBeens.get(i).getLocalPath())) {
                    imagesUploading.add(UploadService.uploadBeens.get(i).copy());
                }
            }
            return imagesUploading.get(0);
        }
        return null;
    }

    public void upload(final int width, final int height) {
        if (cancelUploading || imagesUploading == null || (imagesUploading != null && imagesUploading.size() == 0)) {
            return;
        }
        final UploadBean image = getUploadBean();
        if (image == null) {
            return;
        }
        if (TextUtils.isEmpty(image.getLocalPath()) || image.getLocalPath() == null
                &&(!new File(image.getLocalPath()).exists()||new File(image.getLocalPath()).length()/(1024*1024)<3)) {
            image.setStatus(UploadBean.UPLOAD_TYPE_FAIL);
            imagesUploading.remove(image);
            if(!new File(image.getLocalPath()).exists()){
                image.setFailMsg("待上传文件不存在");
            }else if(new File(image.getLocalPath()).exists()&&new File(image.getLocalPath()).length()/(1024*1024)<3){
                image.setFailMsg("文件太大，请选择3M以内图片");
            }
            if (onBulkImagesUploadListener != null) {
                onBulkImagesUploadListener.onImageUploadFailed(image);
                if (imagesUploading.size() == 0) {
                    onBulkImagesUploadListener.onFinished(imagesUploadFailed);
                    return;
                }
            }
            return;
        }
        String fileName;
        if (null != image && !TextUtils.isEmpty(image.localPath)) {
            fileName = getImage(image.localPath, width, height);
            if (!TextUtils.isEmpty(fileName)) image.localPath = fileName;
        }
        try {
            AliyunFileUploader aliyunFileUploader = new AliyunFileUploader(image.localPath, image.cloudKey, image.bucketName,  context, new AliyunUploadListener() {
                @Override
                public void onSuccess(String cloudKey, String sourceFilePath) {
                    for (int i = 0; i < imagesUploading.size(); i++) {
                        if (imagesUploading.get(i).getCloudKey().equals(cloudKey)) {
                            imagesUploading.remove(i);
                        }
                    }
                    if (onBulkImagesUploadListener != null) {
                        onBulkImagesUploadListener.onImageUploadSucceed(image);
                        if (imagesUploading.size() == 0) {
                            onBulkImagesUploadListener.onFinished(imagesUploadFailed);
                            return;
                        }
                    }
                    tasks.remove(cloudKey);
                    if (!cancelUploading) {
                        upload(width, height);
                    }
                }

                @Override
                public void onProgress(String cloudKey, long progress, long total) {
                    if (onBulkImagesUploadListener != null) {
                        onBulkImagesUploadListener.onImageUploadProgress(image, progress, total);
                        if (System.currentTimeMillis()-image.getCreateTime()>=3*60*1000) {
                            imagesUploadFailed.add(image);
                            tasks.remove(cloudKey);
                            for (int i = 0; i < imagesUploading.size(); i++) {
                                if (imagesUploading.get(i).getCloudKey().equals(cloudKey)) {
                                    imagesUploading.remove(i);
                                }
                            }
                            if (!cancelUploading) {
                                upload(width, height);
                            }
                            if (onBulkImagesUploadListener != null) {
                                onBulkImagesUploadListener.onImageUploadFailed(image);
                                if (imagesUploading.size() == 0) {
                                    onBulkImagesUploadListener.onFinished(imagesUploadFailed);
                                    return;
                                }
                            }
                        }
                    }

                }

                @Override
                public void onFailure(String cloudKey, ServiceException e) {
                    LogUtils.e(TAG, "图片上传失败: " + e.getMessage() + ",CloudKey: " + cloudKey);
                    imagesUploadFailed.add(image);
                    tasks.remove(cloudKey);
                    for (int i = 0; i < imagesUploading.size(); i++) {
                        if (imagesUploading.get(i).getCloudKey().equals(cloudKey)) {
                            imagesUploading.remove(i);
                        }
                    }
                    if (!cancelUploading) {
                        upload(width, height);
                    }
                    if (onBulkImagesUploadListener != null) {
                        onBulkImagesUploadListener.onImageUploadFailed(image);
                        if (imagesUploading.size() == 0) {
                            onBulkImagesUploadListener.onFinished(imagesUploadFailed);
                            return;
                        }
                    }
                }
            });
            if (cancelUploading) {
                return;
            }
            OSSAsyncTask task;
            if (isResume) {
                task = aliyunFileUploader.uploadResume();
            } else {
                task = aliyunFileUploader.upload();
            }
            if (checkTask(image, task)) return;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
    public void upload(final float scale) {
        if (cancelUploading || imagesUploading == null) {
            return;
        }
        final UploadBean image = getUploadBean();
        String fileName;
        if (null != image && !TextUtils.isEmpty(image.localPath)) {
            fileName = getImage(image.localPath, scale);
            if (!TextUtils.isEmpty(fileName)) image.localPath = fileName;
        }
        try {
            AliyunFileUploader aliyunFileUploader = new AliyunFileUploader(image.localPath, image.cloudKey, image.bucketName, (Activity) context, new AliyunUploadListener() {
                @Override
                public void onSuccess(String cloudKey, String sourceFilePath) {
                    for (int i = 0; i < imagesUploading.size(); i++) {
                        if (imagesUploading.get(i).getCloudKey().equals(cloudKey)) {
                            imagesUploading.remove(i);
                        }
                    }
                    if (onBulkImagesUploadListener != null) {
                        onBulkImagesUploadListener.onImageUploadSucceed(image);
                        if (imagesUploading.size() == 0) {
                            onBulkImagesUploadListener.onFinished(imagesUploadFailed);
                            return;
                        }
                    }
                    tasks.remove(cloudKey);
                    if (!cancelUploading) {
                        upload(scale);
                    }
                }

                @Override
                public void onProgress(String cloudKey, long progress, long total) {
                    if (onBulkImagesUploadListener != null) {
                        onBulkImagesUploadListener.onImageUploadProgress(image, progress, total);
                    }
                }

                @Override
                public void onFailure(String cloudKey, ServiceException e) {
                    imagesUploadFailed.add(image);
                    tasks.remove(cloudKey);
                    for (int i = 0; i < imagesUploading.size(); i++) {
                        if (imagesUploading.get(i).getCloudKey().equals(cloudKey)) {
                            imagesUploading.remove(i);
                        }
                    }
                    if (!cancelUploading) {
                        upload(scale);
                    }
                    if (onBulkImagesUploadListener != null) {
                        onBulkImagesUploadListener.onImageUploadFailed(image);
                        if (imagesUploading.size() == 0) {
                            onBulkImagesUploadListener.onFinished(imagesUploadFailed);
                            return;
                        }
                    }
                }
            });
            if (cancelUploading) {
                return;
            }
            OSSAsyncTask task;
            if (isResume) {
                task = aliyunFileUploader.uploadResume();
            } else {
                task = aliyunFileUploader.upload();
            }
            if (checkTask(image, task)) return;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    private String getImage(String srcPath, int width, int height) {
        if (TextUtils.isEmpty(srcPath)) return null;
        FileOutputStream fos = null;
        String fileName = FileUtils.getTempCacheDir() + "/" + System.currentTimeMillis() + ".jpeg";
        try {
            BitmapFactory.Options newOpts = new BitmapFactory.Options();
            newOpts.inJustDecodeBounds = true;
            Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
            newOpts.inJustDecodeBounds = false;
            int w = newOpts.outWidth;
            int h = newOpts.outHeight;
            float wRate = new Float(w) / new Float(width);
            float hRate = new Float(h) / new Float(height);
            int be = wRate > hRate ? Math.round(wRate) : Math.round(hRate);
            if (be < 1) be = 1;
            newOpts.inSampleSize = be;
            bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            if (null != bitmap) {
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
            }
            FileUtils.createFile(fileName);
            fos = new FileOutputStream(new File(fileName));
            fos.write(baos.toByteArray());
            fos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return srcPath;
        } catch (IOException e) {
            e.printStackTrace();
            LogUtils.e(TAG, e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            LogUtils.e(TAG, e.getMessage());
        } finally {
            try {
                if (null != fos)
                    fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return fileName;
    }
    private String getImage(String srcPath, float scale) {
        if (TextUtils.isEmpty(srcPath)) return null;
        FileOutputStream fos = null;
        String fileName = FileUtils.getTempCacheDir() + "/" + System.currentTimeMillis() + ".jpeg";
        try {
            BitmapFactory.Options newOpts = new BitmapFactory.Options();
            newOpts.inJustDecodeBounds = true;
            newOpts.inPreferredConfig = Bitmap.Config.RGB_565;
            Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
            newOpts.inJustDecodeBounds = false;
            int w = newOpts.outWidth;
            int h = newOpts.outHeight;
            float wRate = scale;
            float hRate = scale;
            int be = wRate > hRate ? Math.round(wRate) : Math.round(hRate);
            if (be < 1) be = 1;
            newOpts.inSampleSize = be;
            bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            if (null != bitmap) {
                bitmap.compress(Bitmap.CompressFormat.JPEG, 50, baos);
            }
            FileUtils.createFile(fileName);
            fos = new FileOutputStream(new File(fileName));
            fos.write(baos.toByteArray());
            fos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return srcPath;
        } catch (IOException e) {
            e.printStackTrace();
            LogUtils.e(TAG, e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            LogUtils.e(TAG, e.getMessage());
        } finally {
            try {
                if (null != fos)
                    fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return fileName;
    }

    public void cancelAll() {
        for (String key :
                tasks.keySet()) {
            tasks.get(key).cancel();
        }
        tasks.clear();
    }

    public void checkUpload(ArrayList<UploadBean> uploadBeens) {
        if(imagesUploading!=null&&tasks!=null&&uploadBeens.size()==0){
            imagesUploading.clear();
            for (int i = 0; i < tasks.size(); i++) {
                try {
                    if (tasks.get(i) != null)
                        tasks.get(i).cancel();
                }catch (Exception e){

                }
            }
            tasks.clear();
        }
        if (imagesUploading.size() == 0 && UploadService.uploadBeens!=null&&UploadService.uploadBeens.size() > 0) {
            for (int i = 0; i < UploadService.uploadBeens.size(); i++) {
                if (UploadService.uploadBeens.get(i).getStatus() == UploadBean.UPLOAD_TYPE_WAITTING || !TextUtils.isEmpty(UploadService.uploadBeens.get(i).getLocalPath())) {
                    imagesUploading.add(UploadService.uploadBeens.get(i).copy());
                }
            }
            startUpload();
        }
        if(imagesUploading.size()!=0&&tasks.size()==0){
            startUpload();
        }
    }


    public interface OnBulkImagesUploadListener {

        void onImageUploadProgress(UploadBean image, long progress, long total);

        void onImageUploadSucceed(UploadBean image);

        void onImageUploadFailed(UploadBean image);

        void onFinished(List<UploadBean> imagesUploadFailed);

    }

}
